package com.example.wechat.controller;

import java.security.Principal;
import java.util.Map;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import com.example.project.core.controller.BaseController;
import com.example.project.entity.User;
import com.example.project.service.CommonService;
import com.example.project.utils.DateUtils;
import com.example.wechat.domain.MessageSendResult;
import com.example.wechat.service.WebSocketService;
import com.example.wechat.service.WechatMessageService;

@Controller
@RequestMapping("/wechat")
public class WeChatController extends BaseController {

	private static final Logger log = LoggerFactory.getLogger(WeChatController.class);

	private String prefix = "message/wechat";

	@Autowired
	private CommonService commonService;

	@Autowired
	private WebSocketService webSocketService;

	@Autowired
	private WechatMessageService messageService;

	@RequiresPermissions("message:wechat:view")
	@GetMapping()
	public String notice(ModelMap mmap) {
		// 取身份信息
		User user = getUser();
		mmap.put("user", user);

		// 查询对话

		return prefix + "/wechat";
	}

	/**
	 * 从Principal对象中提取用户ID
	 */
	private String getUserFromPrincipal(Principal principal) {
		try {
			// 使用反射从ObjectPrincipal中提取User对象
			java.lang.reflect.Field objectField = principal.getClass().getDeclaredField("object");
			objectField.setAccessible(true);
			Object userObject = objectField.get(principal);

			if (userObject instanceof User) {
				User user = (User) userObject;
				return String.valueOf(user.getUserId());
			}
		} catch (Exception e) {
			// 如果反射失败，返回默认用户ID
			return "1"; // 默认管理员用户ID
		}
		return "1"; // 默认管理员用户ID
	}

	/**
	 * 处理发送消息的WebSocket请求
	 */
	@MessageMapping("/chat.sendMessage")
	public void sendMessage(@Payload Map<String, Object> messagePayload, Principal principal,
			SimpMessageHeaderAccessor headerAccessor) {
		try {
			String userId = String.valueOf(headerAccessor.getSessionAttributes().get("userId"));
			if (userId == null) {
				System.out.println("会话属性中没有userId，尝试从Principal获取");
				userId = getUserFromPrincipal(principal);
				System.out.println("从Principal获取的userId: " + userId);
			}
			String conversationId = String.valueOf(messagePayload.get("conversationId"));
			String content = (String) messagePayload.get("content");
			String messageType = (String) messagePayload.get("messageType");

			log.info("收到消息发送请求: sender={}, conversation={}", userId, conversationId);

			// 调用消息服务处理消息发送
			MessageSendResult result = messageService.sendMessage(conversationId, userId, content,
					Integer.parseInt(messageType), messagePayload);

			// 为每个接收者推送消息
			for (Long receiverId : result.getReceivers()) {
				if (!receiverId.equals(userId)) { // 不推送给自己
					Map<String, String> pushData = buildPushData(result, userId, receiverId);
					webSocketService.pushNewMessage(String.valueOf(receiverId), pushData);
				}
			}

		} catch (Exception e) {
			log.error("处理消息发送失败", e);
		}
	}

	/**
	 * 处理消息已读状态
	 */
	@MessageMapping("/chat.messageRead")
	public void markMessageAsRead(@Payload Map<String, Object> readPayload, SimpMessageHeaderAccessor headerAccessor) {
		String userId = (String) headerAccessor.getSessionAttributes().get("userId");
		String conversationId = (String) readPayload.get("conversationId");
		Long messageId = Long.valueOf(readPayload.get("messageId").toString());

		// 更新消息已读状态
		Integer unreadCount = messageService.markMessageAsRead(conversationId, userId, messageId);

		// 推送已读状态给其他参与者
		webSocketService.pushMessageReadStatus(conversationId, userId, messageId, unreadCount);
	}

	/**
	 * 处理输入状态
	 */
	@MessageMapping("/chat.typing")
	public void handleTyping(@Payload Map<String, Object> typingPayload, SimpMessageHeaderAccessor headerAccessor) {
		String userId = (String) headerAccessor.getSessionAttributes().get("userId");
		String conversationId = (String) typingPayload.get("conversationId");
		Boolean isTyping = (Boolean) typingPayload.get("isTyping");

		webSocketService.pushTypingStatus(conversationId, userId, isTyping);
	}

	/**
	 * 构建推送数据
	 */
	private Map<String, String> buildPushData(MessageSendResult result, String senderId, Long receiverId) {
		return Map.of("type", "new_message", "messageId", result.getMessageId(), "conversationId",
				result.getConversationId(), "senderId", senderId, "senderName", result.getSenderName(), "content",
				result.getContent(), "messageType", result.getMessageType(), "sendTime",
				DateUtils.formatLocalDateTime(result.getSendTime(), DateUtils.YYYY_MM_DD_HH_MM_SS), "unreadCount",
				String.valueOf(messageService.getUnreadCount(receiverId)));
	}
}